﻿using AvoidForgettingApi.Common;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Formatters;
using Microsoft.AspNetCore.WebUtilities;
using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace AvoidForgettingApi.MiddleWare
{
    public class LoggerMiddleware
    {
        private readonly RequestDelegate _next;

        public LoggerMiddleware(RequestDelegate next)
        {
            _next = next;
        }

        public async Task InvokeAsync(HttpContext context)
        {
            if (!context.Request.Path.ToString().ToLower().Contains("swagger"))
            {
                var method = context.Request.Method;
                var query = "";
                if (context.Request.Query.Count > 0)
                {
                    query = context.Request.QueryString.Value;
                }
                var body = await FormatRequest(context.Request);
                _ = Task.Run(() => CommonHelper.TxtLog("请求日志", $"请求路径:{context.Request.Host}{context.Request.Path};\r\n请求方式:{method};\r\nquery参数:{query};\r\nbody参数:{body}"));
            }
            var originalBodyStream = context.Response.Body;
            using var responseBody = new MemoryStream();
            context.Response.Body = responseBody;
            await _next(context);
            var response = context.Response;
            response.Body.Seek(0, SeekOrigin.Begin);
            //转化为字符串
            string text = await new StreamReader(response.Body).ReadToEndAsync();
            //从新设置偏移量0
            response.Body.Seek(0, SeekOrigin.Begin);
            if (!string.IsNullOrEmpty(text))
            {
                var responsestr = $"{response.StatusCode}: {text}";
                switch (response.StatusCode)
                {
                    case 400:
                        CommonHelper.TxtLog("请求错误日志", responsestr);
                        break;
                    case 401:
                        CommonHelper.TxtLog("认证错误日志", responsestr);
                        break;
                    case 422:
                        CommonHelper.TxtLog("异常日志", responsestr);
                        break;
                    case 200:
                        CommonHelper.TxtLog("正常返回日志", responsestr);
                        break;
                    case 500:
                        CommonHelper.TxtLog("异常日志", responsestr);
                        break;
                    default:

                        CommonHelper.TxtLog("正常返回日志", responsestr);
                        break;
                }
            }

            
                context.Response.StatusCode = 200;

                await responseBody.CopyToAsync(originalBodyStream);


            
        }

        private async Task<string> FormatRequest(HttpRequest request)
        {
            var body = "";

            if (request.ContentLength > 0)
            {
                if (!request.Body.CanSeek)
                {
                    request.EnableBuffering();
                    await request.Body.DrainAsync(CancellationToken.None);
                    request.Body.Seek(0L, SeekOrigin.Begin);
                }

                var contentType = request.ContentType;
                var mediaType = contentType == null ? default : new MediaType(contentType);
                var encoding = mediaType.Encoding;
                if (encoding == null)
                {
                    encoding = Encoding.UTF8;
                }

                using StreamReader sr = new StreamReader(request.Body, encoding, true, 1024, true);
                body = await sr.ReadToEndAsync();
                request.Body.Seek(0, SeekOrigin.Begin);//内容读取完成后需要将当前位置初始化，否则后面的InputFormatter会无法读取

            }
            return body;
        }
    }
}
